package xyz.xtgl;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import common.core.util.CommonUtil;
import common.util.generate.config.MyFreemarkerTemplateEngine;
import common.util.generate.config.MyGenerateConfig;
import org.junit.Test;
import plus.logic.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liubo
 * @created 2020-02-14 14:26
 */
public class ProductGenerate {

    private static String modelName ="product";
    private static String projectNme="xtgl_product";

    private static String[] tables = {
            "b_product_category"
    };


    private static String projectPath =  "C:\\Users\\28060\\IdeaProjects\\xtgl-centrl\\xtgl-business\\xtgl-product\\xtgl-product-service";
    private static String projectApiPath =  "C:\\Users\\28060\\IdeaProjects\\xtgl-centrl\\xtgl-business\\xtgl-product\\xtgl-product-api";

    private void initGenerate() {
        MyGenerateConfig config = new MyGenerateConfig();
        MyFreemarkerTemplateEngine.config = config;
        config.setEntityHelpCreate(true);
        config.setEntityCreate(true);
        config.setFeignCreate(true);
        config.setFeignFallbackCreate(true);


        config.setXmlMapperCreate(true);
        config.setMapperCreate(true);
        config.setDaoCreate(true);
        config.setDaoImplCreate(true);
        config.setServiceCreate(true);
        config.setServiceImplCreate(true);
        config.setControllerCreate(true);


        config.setEditHtmlCreate(true);
        config.setEditJsCreate(true);
        config.setListHtmlCreate(true);
        config.setListJsCreate(true);

        //config.setEntityEmeusCreate(true);
    }

    @Test
    public void generate() {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        //生成哪些文件
        initGenerate();
        // 全局配置
        initGlobalConfig(mpg);
        // 数据源配置
        initDataSourceConfig(mpg);
        // 包配置
        PackageConfig pc = initPackageConfig(mpg);
        // 自定义配置
        initInjectionConfig(mpg, pc);
        // 配置模板
        initTemplateConfig(mpg);
        // 策略配置
        initStrategyConfig(mpg, pc);
        mpg.setTemplateEngine(new MyFreemarkerTemplateEngine());
        mpg.execute();
    }

    private static void initGlobalConfig(AutoGenerator mpg) {
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(projectPath + "\\src\\main\\java");
        gc.setFileOverride(true);
        gc.setAuthor("liubo");
        gc.setOpen(false);
        gc.setSwagger2(true); //实体属性 Swagger2 注解
        gc.setDateType(DateType.ONLY_DATE);
        gc.setBaseResultMap(false);
        gc.setBaseColumnList(false);
        mpg.setGlobalConfig(gc);
    }

    private static void initDataSourceConfig(AutoGenerator mpg) {
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://mysql.gpgl.xyz:3306/xtgl-"+modelName+"?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("liubo5173");
        mpg.setDataSource(dsc);
    }

    private static void initInjectionConfig(AutoGenerator mpg, PackageConfig pc) {
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = CommonUtil.isEmptyReturn(this.getMap(), new HashMap<String, Object>());
                map.put("CommonUtil", CommonUtil.class.getName());
                map.put("superDaoClassPackage", LogicBaseDao.class.getName());
                map.put("superHelpClassPackage", LogicBaseHelp.class.getName());
                map.put("parent", pc.getParent());
                map.put("ID", "String");
                map.put("layuiModelsPath","/lib/modules/");
                map.put("contextPath","/"+modelName);
                map.put("serviceName","SERVICE_NAME_"+projectNme.toUpperCase());
                this.setMap(map);
            }
        };

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig( "/templates/dao.java.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + "/src/main/java/"+toPath(pc.getParent())+
                        "/dao/I" + tableInfo.getEntityName() + "Dao" + StringPool.DOT_JAVA;
            }
        });

        focList.add(new FileOutConfig( "/templates/daoImpl.java.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + "/src/main/java/"+toPath(pc.getParent())+
                        "/dao/impl/" + tableInfo.getEntityName() + "DaoImpl" + StringPool.DOT_JAVA;
            }
        });
//        focList.add(new FileOutConfig( "/templates/emeu.java.ftl") {
//            @Override
//            public String outputFile(TableInfo tableInfo) {
//                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
//                return projectApiPath + "/src/main/java/"+toPath(pc.getParent())+
//                        "/entity/emeus/" + tableInfo.getEntityName() + "Emeus" + StringPool.DOT_JAVA;
//            }
//        });
        focList.add(new FileOutConfig( "/templates/help.java.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectApiPath + "/src/main/java/"+toPath(pc.getParent())+
                        "/entity/help/" + tableInfo.getEntityName() + "Help" + StringPool.DOT_JAVA;
            }
        });
        focList.add(new FileOutConfig( "/templates/feign.java.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectApiPath + "/src/main/java/"+toPath(pc.getParent())+
                        "/feign/" + tableInfo.getEntityName() + "Feign" + StringPool.DOT_JAVA;
            }
        });
        focList.add(new FileOutConfig( "/templates/feignFallback.java.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectApiPath + "/src/main/java/"+toPath(pc.getParent())+
                        "/feign/fallback/" + tableInfo.getEntityName() + "FeignFallback" + StringPool.DOT_JAVA;
            }
        });
        focList.add(new FileOutConfig( "/templates/edit.js.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + "/src/main/resources/static/js/"+modelName+"/"+ CommonUtil.dbForDBToFistLowercaseHump(tableInfo.getEntityName())+
                        "/" + CommonUtil.dbForDBToFistLowercaseHump(tableInfo.getEntityName()) + "_edit.js";
            }
        });
        focList.add(new FileOutConfig( "/templates/list.js.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + "/src/main/resources/static/js/"+modelName+"/"+ CommonUtil.dbForDBToFistLowercaseHump(tableInfo.getEntityName())+
                        "/" + CommonUtil.dbForDBToFistLowercaseHump(tableInfo.getEntityName()) + "_list.js";
            }
        });
        focList.add(new FileOutConfig( "/templates/edit.html.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + "/src/main/resources/static/views/"+modelName+"/"+ CommonUtil.dbForDBToFistLowercaseHump(tableInfo.getEntityName())+
                        "/" + CommonUtil.dbForDBToFistLowercaseHump(tableInfo.getEntityName()) + "_edit.html";
            }
        });
        focList.add(new FileOutConfig( "/templates/list.html.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + "/src/main/resources/static/views/"+modelName+"/"+ CommonUtil.dbForDBToFistLowercaseHump(tableInfo.getEntityName())+
                        "/" + CommonUtil.dbForDBToFistLowercaseHump(tableInfo.getEntityName()) + "_list.html";
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
    }

    private static PackageConfig initPackageConfig(AutoGenerator mpg) {
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(modelName);
        pc.setParent("xyz.xtgl");
        pc.setMapper("dao.impl.mapper");
        pc.setXml("dao.impl.mapper.xml");
        pc.setService("service");
        pc.setServiceImpl("service.impl");
        pc.setController("controller");
        mpg.setPackageInfo(pc);
        Map<String, String> pathInfo = new HashMap<>();
        pathInfo.put(ConstVal.ENTITY_PATH, projectApiPath+ "/src/main/java/"+toPath(pc.getParent())+"/entity");
        pathInfo.put(ConstVal.XML_PATH, projectPath+ "/src/main/java/"+toPath(pc.getParent())+"/"+toPath(pc.getXml()));
        pathInfo.put(ConstVal.MAPPER_PATH, projectPath+ "/src/main/java/"+toPath(pc.getParent())+"/"+toPath(pc.getMapper()));
        pathInfo.put(ConstVal.SERVICE_PATH, projectPath+ "/src/main/java/"+toPath(pc.getParent())+"/"+toPath(pc.getService()));
        pathInfo.put(ConstVal.SERVICE_IMPL_PATH, projectPath+ "/src/main/java/"+toPath(pc.getParent())+"/"+toPath(pc.getServiceImpl()));
        pathInfo.put(ConstVal.CONTROLLER_PATH, projectPath+ "/src/main/java/"+toPath(pc.getParent())+"/"+toPath(pc.getController()));
        pc.setPathInfo(pathInfo);
        return pc;
    }

    private static void initStrategyConfig(AutoGenerator mpg, PackageConfig pc) {
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setSuperEntityClass(LogicBaseEntity.class.getName());
        strategy.setSuperServiceClass(LogicBaseService.class.getName());
        strategy.setSuperServiceImplClass(LogicBaseServiceImpl.class.getName());
        strategy.setSuperControllerClass(LogicBaseController.class.getName());
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setSuperControllerClass(LogicBaseController.class.getName());
        strategy.setSuperMapperClass(LogicBaseMapper.class.getName());
        strategy.setInclude(tables);
        strategy.setSuperEntityColumns("id","version","create_user","create_time","modify_user","modify_time","removed");
        strategy.setControllerMappingHyphenStyle(true);
        mpg.setStrategy(strategy);
    }

    private static void initTemplateConfig(AutoGenerator mpg) {
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        //指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        templateConfig.setController("templates/controller.java");
        templateConfig.setEntity("templates/entity.java");
        templateConfig.setMapper("templates/mapper.java");
        templateConfig.setService("templates/service.java");
        templateConfig.setServiceImpl("templates/serviceImpl.java");
        mpg.setTemplate(templateConfig);
    }

    private static String toPath(String str) {
        String[] arr = str.split("\\.");
        String result = "";
        for(String st:arr) {
            if(result.length()!=0) {
                result+="/";
            }
            result+=st;
        }
        return result;
    }

}